package basicelement;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;

import com.rapidminer.example.Attribute;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.generator.FloorCeilGenerator;
import com.rapidminer.operator.IOContainer;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.io.ExampleSource;
import com.rapidminer.tools.OperatorService;

import istar.IElement;
import istar.agent.IstarJadeAgent;
import istar.behaviour.AbstractIstarBehaviour;
import istar.impl.AbstractBasicResource;
import istar.impl.AbstractBasicTask;
import istar.impl.TaskDecompositionLink;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.OneShotBehaviour;

public class AssemblySellOrder extends AbstractBasicTask {

	private boolean log = true;
		
		public AssemblySellOrder() {
			super("AssemblySellOrder"); 
		}

		@Override
		public Behaviour getBehaviour() {
			//return new myBehaviour((IstarJadeAgent)this.getOwner(), this);
			return new myBehaviour(this);
		}
		
		private class myBehaviour extends AbstractIstarBehaviour{

			AbstractBasicTask task;
			private int estimatedTime = 100;
			
			public myBehaviour(AbstractBasicTask _task){
				super(_task);
			}

			@Override
			public long getEstimatedWaitingTime() {
				return estimatedTime;
			}

			@Override
			public void myAction() {
				
				System.out.println("AssemblySellOrder executing");
				log("AssemblySellOrder");

				Integer qttlowStock = (Integer)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "LowStockQtt");
				Integer qtthighStock = (Integer)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStockQtt");
				String lowStockName = (String)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "LowStockName");
				String highStockName = (String)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStockName");
				
				
				
				try {
					/*
					Example stockOptionPrices = null;
					IElement previousTask = (IElement)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), ((AbstractBasicTask)getElement()).getPreviousElement().getId());
					for (int i=0;i<previousTask.getContent().size();i++){
						if (previousTask.getContent().get(i).getClass().equals(Example.class))
							stockOptionPrices = (Example)previousTask.getContent().get(i);
					}
					if (stockOptionPrices==null)
						throw new Exception("StockOptionPrices not found");

					Attribute lowStockAtt = stockOptionPrices.getAttributes().get(lowStockName);
					Double lowStockPrice = stockOptionPrices.getValue(lowStockAtt);
					
					Attribute highStockAtt = stockOptionPrices.getAttributes().get(highStockName);
					Double highStockPrice = stockOptionPrices.getValue(highStockAtt);

					System.out.println("stockoption prices: "+ lowStockName + "=" + lowStockPrice + ";"+ highStockName + "="+ highStockPrice);
					*/
					
					String time = (String)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "SimulationTime");
					Double money = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "Money");
					Double brokerageFee = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "BrokerageFee");
					Double highStrike = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStrike");
					Double lowStrike = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "LowStrike");
					Double lowStockPrice = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "LowStockPrice");
					Double highStockPrice = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStockPrice");
					
					Double spread = highStrike-lowStrike;
					

					String order=sellOrder(time, lowStockPrice, highStockPrice, money, qttlowStock, qtthighStock, spread, brokerageFee);

					IElement endElement = getElement().getSupports().get(0).getOwner();
					endElement.getContent().clear();
					endElement.getContent().add(order);
					System.out.println("Order: " + order);
					((IstarJadeAgent)myAgent).setKnowledgeObject(getElement().getExecutionNumber(), "Order", order);

				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
			
			
			private String sellOrder(String _time, Double _lowStockPrice, Double _highStockPrice, 
									 Double _money, Integer _qttLowStock, Integer _qttHighStock,
									 Double _strikesGap, Double _brokerageFee) throws Exception {
			    Double money = _money;
			    long quantityHigh = 0, quantityLow=0;
			    Double blocked = new Double(0);
		    	// zero position
		    	if ((_qttLowStock==0)&&(_qttHighStock==0)){
		    		quantityHigh = Math.round((_money - _brokerageFee)/(_highStockPrice+_strikesGap));
		    		quantityHigh = Math.round(quantityHigh/100)*100;
		    		blocked = quantityHigh*_strikesGap;
		    		quantityLow = -quantityHigh;
		    		money += quantityLow*_lowStockPrice -quantityHigh*_highStockPrice;
		    	}
		    	// bought position
		    	else if ((_qttLowStock==0)&&(_qttHighStock>0)) {
		    		quantityHigh = Math.round(((_qttHighStock*_highStockPrice) - _brokerageFee)/(_highStockPrice+_strikesGap));
		    		quantityHigh = Math.round(quantityHigh/100)*100;
		    		blocked = quantityHigh*_strikesGap;
		    		quantityLow = -quantityHigh;
		    		money += (quantityHigh-_qttHighStock)*_highStockPrice - quantityLow*_lowStockPrice;
		    		quantityHigh = quantityHigh-_qttHighStock;
		    		
		    	}
		    	// sold position
		    	else if (_qttLowStock<0){
		    		quantityHigh = _qttHighStock;
		    		quantityLow = _qttLowStock;
		    	}
		    	else {
		    		throw new Exception("Incosistent position : QttLowStock="+ _qttHighStock+ " QttLowStock=" + _qttLowStock);
		    	}
			    	
		    	return _time +";qttlowstock=" + quantityLow+ ";qtthighstock=" + quantityHigh + ";money=" + money + 
	    		  ";blocked=" +	blocked + ";lowstockprice=" + _lowStockPrice + ";highstockprice" + _highStockPrice + ";previous-money=" + _money ;
			    
			}


			
			private TendencyIndicator getLastTendency(){
				TendencyIndicator lastTend = null;
				Iterator<Object> itMems = ((IstarJadeAgent)myAgent).getShortTermMemory().values().iterator();
				while (itMems.hasNext()){
					Object memObj = itMems.next();
					if (memObj.getClass().equals(TendencyIndicator.class)){
						if (lastTend != null){
							if (((TendencyIndicator)memObj).getInstantTime().after(lastTend.getInstantTime()))
								lastTend = (TendencyIndicator)memObj;
						}
						else {
							lastTend = (TendencyIndicator)memObj;
						}
					}
				}
				return lastTend;
			}

			
			@Override
			public int myOnEnd() {
				// TODO Auto-generated method stub
				return 1;
			}

			@Override
			public boolean done() {
				return true;
			}
		}
}

